package com.fmn.dots_final_i_hope;

import java.util.ArrayList;
import java.util.Collections;

import model.GameField;
import model.LineHorizontal;
import model.LineVertical;
import model.Square;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TableLayout;
import android.widget.TableRow;


public class PlayerVsComputerActivity extends Activity {

	
	ImageView[][] gameField;
	ArrayList<Square> squares = new ArrayList<Square>();
	TableLayout tl;
	ArrayList<TableRow> tableRows;
	public EditText pl1;
	public EditText pl2;
	public EditText currPlay;


	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		PlayerControl.p1.setChosenImage(PlayerControl.chosenPic1);
		PlayerControl.p2.setChosenImage(PlayerControl.chosenPic2);

		if (PlayerControl.choosenCol == 3 && PlayerControl.choosenRow == 3) {
			setContentView(R.layout.field_3x3);
		} else if (PlayerControl.choosenCol == 4
				&& PlayerControl.choosenRow == 3) {
			setContentView(R.layout.field_4x3);

		} else if (PlayerControl.choosenCol == 4
				&& PlayerControl.choosenRow == 4) {
			setContentView(R.layout.field_4x4);

		} else if (PlayerControl.choosenCol == 5
				&& PlayerControl.choosenRow == 4) {
			setContentView(R.layout.field_5x4);

		} else if (PlayerControl.choosenCol == 5
				&& PlayerControl.choosenRow == 5) {
			setContentView(R.layout.field_5x5);

		}
		
		 tl = (TableLayout) findViewById(R.id.tableLayout1);
		 tableRows = getTableRowsFromTablelayout(tl);
		
		
		gameField = new ImageView[PlayerControl.choosenCol * 2 + 1][PlayerControl.choosenRow * 2 + 1];

		PlayerControl.maxPointsPossible = (PlayerControl.choosenCol)
				* (PlayerControl.choosenRow);

		for (int i = 0; i < gameField.length; i++) {
			for (int j = 0; j < gameField[i].length; j++) {
				String drawObjectID = "drawObject_" + i + "_" + j;
				int resID = getResources().getIdentifier(drawObjectID, "id",
						getPackageName());
				gameField[i][j] = ((ImageView) findViewById(resID));

			}
		}

		// ---these are just for test visualisation

		pl1 = (EditText) findViewById(R.id.editTextP1);
		pl2 = (EditText) findViewById(R.id.editTextP2);

		currPlay = (EditText) findViewById(R.id.editTexCurr);

		pl2.setText(Integer.toString(PlayerControl.p2.getCurrentPoints()));
		pl1.setText(Integer.toString(PlayerControl.p1.getCurrentPoints()));

		currPlay.setText(PlayerControl.getCurrentPlayer().getName());

		// ----

		// Setting connections between Lines and Squares

		GameField.setReferences(gameField);

		// Setting touch listeners for Lines - could be re-factored into method

		for (int i = 0; i < gameField.length; i++) {
			for (int j = 0; j < gameField[i].length; j++) {

				if (i % 2 == 0 && j % 2 != 0) {
					gameField[i][j].setOnTouchListener(horizontalPressed);
				}
				if (i % 2 != 0 && j % 2 == 0) {
					gameField[i][j].setOnTouchListener(verticalPressed);
				}

			}
		}

	}

	View.OnTouchListener horizontalPressed = new View.OnTouchListener() {

		@Override
		public boolean onTouch(View v, MotionEvent event) {

			LineHorizontal lineH = (LineHorizontal) v;

			if (event.getAction() == MotionEvent.ACTION_DOWN) {
				if(PlayerControl.getCurrentPlayer().equals(PlayerControl.p1))
					doAPlayerTurnH(lineH);

				
			if(PlayerControl.getCurrentPlayer().equals(PlayerControl.p2)){
					doAITurn();
				}
				return true;
			}
			
			return false;
		}

		

	};
private void doAPlayerTurnH(LineHorizontal lineH) {
			if (lineH.isPressed() == false) {
				lineH.setPressed(true);

				if (lineH.tryToObtainSquare() == false)
					PlayerControl.changePlayer();

				currPlay.setText(PlayerControl.getCurrentPlayer().getName());

				pl2.setText(Integer.toString(PlayerControl.p2
						.getCurrentPoints()));
				pl1.setText(Integer.toString(PlayerControl.p1
						.getCurrentPoints()));
				if (PlayerControl.checkForEndGame())
					showEndGameDialog();

			}
		}
	View.OnTouchListener verticalPressed = new View.OnTouchListener() {

		@Override
		public boolean onTouch(View v, MotionEvent event) {

			LineVertical lineV = (LineVertical) v;

			if (event.getAction() == MotionEvent.ACTION_DOWN) {
				if(PlayerControl.getCurrentPlayer().equals(PlayerControl.p1))
				doAPlayerTurnV(lineV);
				
				if (PlayerControl.checkForEndGame())
					showEndGameDialog();
				if(PlayerControl.getCurrentPlayer().equals(PlayerControl.p2)){
					doAITurn();
				}
				return true;
			}
			
			return false;
		}

		

	};
	private void doAPlayerTurnV(LineVertical lineV) {
		if (lineV.isPressed() == false) {
			lineV.setPressed(true);

			if (lineV.tryToObtainSquare() == false)
				PlayerControl.changePlayer();

			currPlay.setText(PlayerControl.getCurrentPlayer().getName());

			pl2.setText(Integer.toString(PlayerControl.p2
					.getCurrentPoints()));
			pl1.setText(Integer.toString(PlayerControl.p1
					.getCurrentPoints()));
			if (PlayerControl.checkForEndGame())
				showEndGameDialog();
		}
	}

	private void showEndGameDialog() {
		AlertDialog.Builder dBuilder = new AlertDialog.Builder(this);

		String msg = "The winner is: " + PlayerControl.anounceWinner()
				+ "\nPoints: " + PlayerControl.p1.getCurrentPoints() + " : "
				+ PlayerControl.p2.getCurrentPoints();

		dBuilder.setTitle("GAME OVER");
		dBuilder.setMessage(msg);

		dBuilder.setPositiveButton("REMATCH",
				new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						PlayerControl.nullPoints();
						Intent rematchIntent = new Intent(
								PlayerVsComputerActivity.this,
								PlayerVsComputerActivity.class);
						PlayerVsComputerActivity.this
								.startActivity(rematchIntent);

					}
				});

		dBuilder.setNegativeButton("TO MAIN MENU",
				new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						PlayerControl.nullPoints();
						Intent goToMainMenuIntent = new Intent(
								PlayerVsComputerActivity.this,
								MenuActivity.class);
						PlayerVsComputerActivity.this
								.startActivity(goToMainMenuIntent);

					}
				});

		AlertDialog endGame = dBuilder.create();
		endGame.show();

	}

	private void doAITurn() {
		
			addSquaresToArrayList(squares,tableRows);
			Collections.shuffle(squares);
			pressAILine();
			squares.clear();
			
			if(PlayerControl.getCurrentPlayer().equals(PlayerControl.p2) && !PlayerControl.checkForEndGame()){
				doAITurn();
			}
		
	}

	private void pressAILine() {
		final int BEST_CASE_OF_SQUARE_LINES = 1;
		final int NORMAL_CASE_OF_SQUARE_LINES = 3;
		final int NORMAL_CASE_OF_SQUARE_LINES_2 = 4;
		final int NORMAL_CASE_OF_SQUARE_LINES_3 = 0;
		final int WORST_CASE_OF_SQUARE_LINES = 2;
		
		for (Square sq : squares) {
			if (sq.getNumOfNotPressedLines() == BEST_CASE_OF_SQUARE_LINES) {
				findAndPressALine(sq);
				return;
			}
		}
		for (Square sq : squares) {
			if (sq.getNumOfNotPressedLines() == NORMAL_CASE_OF_SQUARE_LINES
					|| sq.getNumOfNotPressedLines() == NORMAL_CASE_OF_SQUARE_LINES_2
					|| sq.getNumOfNotPressedLines() == NORMAL_CASE_OF_SQUARE_LINES_3) {
				findAndPressALine(sq);
				return;
			} 
		}
		for (Square sq : squares) {
				if (sq.getNumOfNotPressedLines() == WORST_CASE_OF_SQUARE_LINES) {
					findAndPressALine(sq);
					return;
				}
			}
		}
		
			

	private void findAndPressALine(Square sq) {
		ImageView line = findWhichLineToPress(sq);
		
		if(line instanceof LineHorizontal){
			LineHorizontal lineH = (LineHorizontal) line;
			doAPlayerTurnH(lineH);
		}
		
		if(line instanceof LineVertical){
			LineVertical lineV = (LineVertical) line;
			doAPlayerTurnV(lineV);
		}
	}

	private ImageView findWhichLineToPress(Square sq) {
		ArrayList<ImageView> arrayWithLines = new ArrayList<ImageView>();
		
		if(!sq.getLeftLine().isPressed())
			arrayWithLines.add(sq.getLeftLine());
		if(!sq.getRightLine().isPressed())
			arrayWithLines.add(sq.getRightLine());
		if(!sq.getUpperLine().isPressed())
			arrayWithLines.add(sq.getUpperLine());
		if(!sq.getDownLine().isPressed())
			arrayWithLines.add(sq.getDownLine());
		
		Collections.shuffle(arrayWithLines);
		
		return arrayWithLines.get(0);
	}


	private void addSquaresToArrayList(ArrayList<Square> putTo,ArrayList<TableRow> tableRows) {
		for(TableRow tr : tableRows){
			int childCount = tr.getChildCount();
			for(int i=0;i<childCount;i++){
				if(tr.getChildAt(i) instanceof Square){
					Square child = (Square) tr.getChildAt(i);
					if(!child.getAlreadyObtained()){
						int numOfFreeLines = findHowManyFreeLinesHas(child);
						child.setNumOfNotPressedLines(numOfFreeLines);
						putTo.add(child);
					}
				}
			}
		}
	}

	private ArrayList<TableRow> getTableRowsFromTablelayout(TableLayout tl) {
		int childCount = tl.getChildCount();
		ArrayList<TableRow> children = new ArrayList<TableRow>();
		
		for(int i=0;i<childCount;i++){
			
			if(tl.getChildAt(i) instanceof TableRow){
				
				TableRow child = (TableRow) tl.getChildAt(i);
				children.add(child);
			}
		}
		return children;
	}

	
	private int findHowManyFreeLinesHas(Square s) {
		int freeLines = 0;
		if(!s.getLeftLine().isPressed())
			freeLines++;
		if(!s.getRightLine().isPressed())
			freeLines++;
		if(!s.getUpperLine().isPressed())
			freeLines++;
		if(!s.getDownLine().isPressed())
			freeLines++;
		return freeLines;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}
